package can

import (
	"gitee.com/dayu1985/can_api/service/base"
	"gitee.com/dayu1985/can_api/models/views"
	"encoding/json"
	"gitee.com/dayu1985/can_api/models/mgos"
	"time"
	"gitee.com/dayu1985/can_api/errors"
	"gitee.com/dayu1985/can_api/utils"
)

type FactoryIndexParam struct {
	Factory string `json:"factory"`
}

type RealTimeParam struct {
	MidwayNo  []string `json:"midwayno"`  //集中器编号
	StationNo []string `json:"stationno"` //站点集合,只有当MidwayNo个数为1时有效
}

type TimeParam struct {
	StratTime int64    `json:"strattime"` //开始时间
	StationNo []string `json:"stationno"` //站点集合,只有当MidwayNo个数为1时有效
}

type MidwayParam struct {
	MidwayNo string      `json:"midwayno"` //中层编号
	Times    []TimeParam `json:"times"`    //时间请求集合
}

type RealTime2Param struct {
	Midways []MidwayParam `json:"midways"` //时间请求集合
}

type HisReposrtTimePartParam struct {
	Strat int64 `json:"strat"` //开始索引
	End   int64 `json:"end"`   //截止索引
}

type HisReposrtTimeParam struct {
	StratTime int64                     `json:"strattime"` //开始时间
	EndTime   int64                     `json:"endtime"`   //结束时间
	TimeParts []HisReposrtTimePartParam `json:"timeparts"` //排版明细
	StationNo []string                  `json:"stationno"` //站点集合
}

type HisReposrtMidwayParam struct {
	MidwayNo string                `json:"midwayno"` //中层编号
	Times    []HisReposrtTimeParam `json:"times"`    //时间请求集合
}

type HisReposrtParam struct {
	Midways []HisReposrtMidwayParam `json:"midways"` //时间请求集合
}

type HisParam struct {
	MidwayNo  []string `json:"midwayno"`  //中间
	StationNo []string `json:"stationno"` //站点集合,只有当MidwayNo个数为1时有效
	Status    []int    `json:"status"`    //状态
	StartTime int64    `json:"starttime"` //查询起始时间
	EndTime   int64    `json:"endtime"`   //查询截止时间
	MinValue  int      `json:"minvalue"`  //最小值
	MaxValue  int      `json:"maxvalue"`  //最大值
}

type PacketParam struct {
	MidwayNo  []string `json:"midwayno"`  //中间
	StartTime int      `json:"starttime"` //查询起始时间
	EndTime   int      `json:"endtime"`   //查询截止时间
}

type StatusParam struct {
	MidwayNo  string `json:"midwayno"`  //中间
	StationNo string `json:"stationno"` //站点集合,只有当MidwayNo个数为1时有效
	StartTime int    `json:"starttime"` //查询起始时间
	EndTime   int    `json:"endtime"`   //查询截止时间
}

type PacketInfoParam struct {
	MidwayNo  string `json:"midwayno"`  //中间
	StartTime int    `json:"starttime"` //查询起始时间
	EndTime   int    `json:"endtime"`   //查询截止时间
}

func (this *CanService) RealTime(param *RealTimeParam) (interface{}, error) {
	var midways = []views.MidWay_View{}
	if (len(param.MidwayNo) == 1) {
		midway := new(views.MidWay_View)
		stations := []views.Station_View{}
		midway.MidwayNo = param.MidwayNo[0]
		if (len(param.StationNo) == 0) {
			val, err := this.E.Redis.HGetAll(param.MidwayNo[0]).Result()
			if err != nil {
				panic(err)
			}
			for k, v := range val {
				var station views.Station_View
				if err := json.Unmarshal([]byte(v), &station); err == nil {
					station.StationNo = k
					stations = append(stations, station)
				}
			}
		} else {
			for _, no := range param.StationNo {
				val, err := this.E.Redis.HGet(param.MidwayNo[0], no).Result()
				if err != nil {
					continue
				}
				var station views.Station_View
				if e := json.Unmarshal([]byte(val), &station); e == nil {
					station.StationNo = no
					stations = append(stations, station)
				}
			}
		}
		midway.Stations = stations
		midways = append(midways, *midway)
	} else if (len(param.MidwayNo) > 1) {
		for _, midwayno := range param.MidwayNo {
			val, err := this.E.Redis.HGetAll(midwayno).Result()
			if err != nil {
				continue
			}
			midway := new(views.MidWay_View)
			stations := []views.Station_View{}
			midway.MidwayNo = midwayno
			for k, v := range val {
				var station views.Station_View
				if err := json.Unmarshal([]byte(v), &station); err == nil {
					station.StationNo = k
					stations = append(stations, station)
				}
			}
			midway.Stations = stations
			midways = append(midways, *midway)
		}
	}
	return midways, nil
}

/**
*获取实时
 */
func (this *CanService) RealTime2(param RealTime2Param) (interface{}, error) {
	var midways = []views.MidWay2_View{}

	now := time.Now().Unix()
	tz, _ := time.ParseInLocation("2006-01-02", time.Now().Format("2006-01-02"), time.Local)
	zero := tz.Unix()

	for _, m := range param.Midways {
		midway := new(views.MidWay2_View)
		midway.MidwayNo = m.MidwayNo
		stations := []views.Station2_View{}
		val, err := this.E.Redis.HGetAll(m.MidwayNo).Result()
		if err != nil {
			panic(err)
		}

		for _, t := range m.Times {
			start := (t.StratTime - zero) / 1800
			end := (now - zero) / 1800
			if (now-zero)%1800 > 0 {
				end = end + 1
			}

			for _, s := range t.StationNo {
				var data views.Station_Data
				if st, ok := val[s]; ok {
					if e := json.Unmarshal([]byte(st), &data); e == nil {
						station := new(views.Station2_View)
						station.StationNo = s
						station.Value = data.Value
						station.Value1 = data.Value1
						station.Time = data.Time
						station.PerTime = data.PerTime
						station.Status = data.Status
						station.LastTime = now - data.PerTime
						efficiency := 0
						if t.StratTime < data.Time {
							station.LastTime = now - data.PerTime
							if start < 0 {
								for i := 48 + start; i >= 0 && i < 48; i ++ {
									efficiency += data.Efficiency[i]
								}
								for i := 0; i < int(end); i ++ {
									efficiency += data.Efficiency[i]
								}
							} else {
								for i := start; i < end; i ++ {
									efficiency += data.Efficiency[i]
								}
							}
						}
						if (int64(efficiency) > (now - t.StratTime)) {
							efficiency -= data.Efficiency[int(end)-1]
						}
						station.Efficiency = float64(efficiency) / float64(now-t.StratTime)

						stations = append(stations, *station)
					}
				}
			}
		}
		midway.Stations = stations
		midways = append(midways, *midway)
	}

	return midways, nil
}

func (this *CanService) SwitchReport(param *HisParam) (interface{}, error) {

	condition := make(map[string]interface{})

	if param.StartTime == 0 {
		return nil, errors.ParamDataNilErr()
	}

	if (param.EndTime == 0) {
		condition["time"] = map[string]interface{}{"$gte": param.StartTime}
	} else if (param.EndTime > 0) {
		condition["$or"] = [...]map[string]interface{}{map[string]interface{}{"time": map[string]interface{}{"$gte": param.StartTime, "$lte": param.EndTime}},
			map[string]interface{}{"$and": [...]map[string]interface{}{map[string]interface{}{"time": map[string]interface{}{"$gt": param.EndTime}, "pertime": map[string]interface{}{"$lt": param.EndTime}}}}}
	}

	if (param.MinValue > 0 && param.MaxValue == 0) {
		condition["value"] = map[string]interface{}{"$gte": param.MinValue}
		condition["value1"] = map[string]interface{}{"$gte": param.MinValue}
	} else if (param.MinValue == 0 && param.MaxValue > 0) {
		condition["value"] = map[string]interface{}{"$lte": param.MaxValue}
		condition["value1"] = map[string]interface{}{"$lte": param.MaxValue}
	} else if (param.MinValue > 0 && param.MaxValue > 0) {
		condition["value"] = map[string]interface{}{"$gte": param.MinValue, "$lte": param.MaxValue}
		condition["value1"] = map[string]interface{}{"$gte": param.MinValue, "$lte": param.MaxValue}
	}

	if (len(param.Status) > 0) {
		condition["status"] = map[string]interface{}{"$in": param.Status}
	}

	if (len(param.MidwayNo) == 1 && len(param.StationNo) > 0) {
		condition["stationno"] = map[string]interface{}{"$in": param.StationNo}
	}
	condition["midwayno"] = map[string]interface{}{"$in": param.MidwayNo}

	v := make([]mgos.STSwitch, 0)
	err := this.S.HDGetAll(condition, &v)
	if err != nil {
		return nil, err
	}
	ms := make(map[string][]mgos.STSwitch, 0)

	for _, obj := range param.MidwayNo {
		if _, ok := ms[obj]; !ok {
			ms[obj] = make([]mgos.STSwitch, 0)
		}
	}

	for _, obj := range v {
		ms[*obj.MidWayNo] = append(ms[*obj.MidWayNo], obj)
	}

	var midways = []views.MidWay_View{}

	for k, v := range ms {
		midway := new(views.MidWay_View)
		midway.MidwayNo = k
		midway.Stations = make([]views.Station_View, 0)
		stations := make(map[string]views.Station_View, 0)
		for _, s := range v {
			var first mgos.STSwitch
			//填充开始值
			if (s.PerTime < param.StartTime && s.Time > param.StartTime) {
				condition1 := make(map[string]interface{})
				condition1["$and"] = [...]map[string]interface{}{map[string]interface{}{"time": s.PerTime, "stationno": s.StationNo, "midwayno": s.MidWayNo}}

				v1 := make([]mgos.STSwitch, 0)
				err := this.S.HDGetAll(condition1, &v1)
				if err != nil {
					return nil, err
				}
				if len(v1) > 0 {
					first = v1[0]
					staion := new(views.Station_View)
					staion.StationNo = *first.StationNo
					staion.Value = *first.Value
					if first.Value1 != nil {
						staion.Value1 = *first.Value1
					}
					staion.Time = param.StartTime
					staion.Status = *first.Status
					midway.Stations = append(midway.Stations, *staion)
				}
			}

			staion := new(views.Station_View)
			staion.StationNo = *s.StationNo
			if (s.Time >= param.EndTime && param.EndTime != 0) {
				staion.Time = param.EndTime
				if (first.StationNo != nil && len(*first.StationNo) > 0) {
					staion.Value = *first.Value
					if first.Value1 != nil {
						staion.Value1 = *first.Value1
					}
					staion.Status = *first.Status
				} else {
					continue
				}
			} else {
				staion.Time = s.Time
				staion.Value = *s.Value
				if s.Value1 != nil {
					staion.Value1 = *s.Value1
				}
				staion.Status = *s.Status
			}
			midway.Stations = append(midway.Stations, *staion)

			stations[*s.StationNo] = *staion
		}

		//===========================增加实时数据处理，这里主要是为了把长时间运行或停止到现在为止依然未变==================================
		val, err := this.E.Redis.HGetAll(midway.MidwayNo).Result()
		if err != nil && val == nil {
			panic(err)
		}
		if (len(param.MidwayNo) == 1 && len(param.StationNo) > 0) {
			for _, s := range param.StationNo {
				if st, ok := val[s]; ok {
					var data views.Station_Data
					if e := json.Unmarshal([]byte(st), &data); e == nil {
						if (data.PerTime <= param.StartTime && data.Time >= param.StartTime) {
							staion := new(views.Station_View)
							staion.StationNo = s
							staion.Value = data.Value
							staion.Value1 = data.Value1
							staion.Time = param.StartTime
							staion.Status = data.Status
							midway.Stations = append(midway.Stations, *staion)
							stations[s] = *staion
						}
					}
				}
			}
		} else {
			for k1, v1 := range val {
				var data views.Station_Data
				if e := json.Unmarshal([]byte(v1), &data); e == nil {
					if (data.PerTime <= param.StartTime && data.Time >= param.StartTime) {
						staion := new(views.Station_View)
						staion.StationNo = k1
						staion.Value = data.Value
						staion.Value1 = data.Value1
						staion.Time = param.StartTime
						staion.Status = data.Status
						midway.Stations = append(midway.Stations, *staion)
						stations[k1] = *staion
					}
				}
			}
		}

		for _, s := range stations {
			//如果已经是最后一个时间（数据库或Radis中保存的时间大于请求时间，是需要截止的）
			if (s.Time == param.EndTime) {
				continue
			}
			staion := new(views.Station_View)
			staion.StationNo = s.StationNo
			staion.Value = s.Value
			staion.Value1 = s.Value1
			staion.Status = s.Status
			if param.EndTime == 0 {
				staion.Time = time.Now().Unix()
			} else {
				staion.Time = param.EndTime
			}
			midway.Stations = append(midway.Stations, *staion)
		}
		//=============================================================

		midways = append(midways, *midway)
	}

	return midways, nil
}

func (this *CanService) HisReport(param *HisParam) (interface{}, error) {

	condition := make(map[string]interface{})

	if (param.StartTime > 0 && param.EndTime == 0) {
		condition["time"] = map[string]interface{}{"$gte": param.StartTime}
	} else if (param.StartTime == 0 && param.EndTime > 0) {
		condition["time"] = map[string]interface{}{"$lte": param.EndTime}
	} else if (param.StartTime > 0 && param.EndTime > 0) {
		condition["time"] = map[string]interface{}{"$gte": param.StartTime, "$lte": param.EndTime}
	}

	if (param.MinValue > 0 && param.MaxValue == 0) {
		condition["value"] = map[string]interface{}{"$gte": param.MinValue}
		condition["value1"] = map[string]interface{}{"$gte": param.MinValue}
	} else if (param.MinValue == 0 && param.MaxValue > 0) {
		condition["value"] = map[string]interface{}{"$lte": param.MaxValue}
		condition["value1"] = map[string]interface{}{"$lte": param.MaxValue}
	} else if (param.MinValue > 0 && param.MaxValue > 0) {
		condition["value"] = map[string]interface{}{"$gte": param.MinValue, "$lte": param.MaxValue}
		condition["value1"] = map[string]interface{}{"$gte": param.MinValue, "$lte": param.MaxValue}
	}

	if (len(param.Status) > 0) {
		condition["status"] = map[string]interface{}{"$in": param.Status}
	}

	if (len(param.MidwayNo) == 1 && len(param.StationNo) > 0) {
		condition["stationno"] = map[string]interface{}{"$in": param.StationNo}
	}
	condition["midwayno"] = map[string]interface{}{"$in": param.MidwayNo}

	v := make([]mgos.STSwitch, 0)
	err := this.His.HDGetAll(condition, &v)
	if err != nil {
		return nil, err
	}
	ms := make(map[string][]mgos.STSwitch, 0)
	for _, obj := range v {
		if _, ok := ms[*obj.MidWayNo]; !ok {
			ms[*obj.MidWayNo] = make([]mgos.STSwitch, 0)
		}
		ms[*obj.MidWayNo] = append(ms[*obj.MidWayNo], obj)
	}

	var midways = []views.MidWay_View{}
	for k, v := range ms {
		midway := new(views.MidWay_View)
		midway.MidwayNo = k
		midway.Stations = make([]views.Station_View, 0)
		for _, s := range v {
			staion := new(views.Station_View)
			staion.StationNo = *s.StationNo
			staion.Value = *s.Value
			if s.Value1 != nil {
				staion.Value1 = *s.Value1
			}
			staion.Time = s.Time
			staion.Status = *s.Status
			midway.Stations = append(midway.Stations, *staion)
		}
		midways = append(midways, *midway)
	}
	return midways, nil
}

func (this *CanService) PacketReport(param *PacketParam) (interface{}, error) {

	condition := make(map[string]interface{})

	if (param.StartTime > 0 && param.EndTime == 0) {
		condition["t"] = map[string]interface{}{"$gte": param.StartTime}
	} else if (param.StartTime == 0 && param.EndTime > 0) {
		condition["t"] = map[string]interface{}{"$lte": param.EndTime}
	} else if (param.StartTime > 0 && param.EndTime > 0) {
		condition["t"] = map[string]interface{}{"$gte": param.StartTime, "$lte": param.EndTime}
	}

	condition["value.sn"] = map[string]interface{}{"$in": param.MidwayNo}

	v := make([]mgos.Packet, 0)
	err := this.P.HDGetAll(condition, &v)
	if err != nil {
		return nil, err
	}
	var packets = []views.Packet_View{}
	for _, obj := range v {
		packet := new(views.Packet_View)
		packet.Time = *obj.Time
		packet.Source = *obj.Source
		packet.Value = *obj.Value.In
		packet.MidwayNo = *obj.Value.Sn
		packets = append(packets, *packet)
	}

	return packets, nil
}

func (this *CanService) StatusReport(param *StatusParam) (interface{}, error) {

	//condition := make(map[string]interface{})
	//
	//if (param.StartTime == 0) {
	//	return nil, errors.MgoQueryParamErr()
	//}
	//if (param.EndTime == 0) {
	//	condition["time"] = map[string]interface{}{"$gte": param.StartTime}
	//} else if (param.EndTime > 0) {
	//	condition["time"] = map[string]interface{}{"$gte": param.StartTime}
	//	condition["pertime"] = map[string]interface{}{"$lte": param.EndTime}
	//}
	//
	//if (param.MinValue > 0 && param.MaxValue == 0) {
	//	condition["value"] = map[string]interface{}{"$gte": param.MinValue}
	//	condition["value1"] = map[string]interface{}{"$gte": param.MinValue}
	//} else if (param.MinValue == 0 && param.MaxValue > 0) {
	//	condition["value"] = map[string]interface{}{"$lte": param.MaxValue}
	//	condition["value1"] = map[string]interface{}{"$lte": param.MaxValue}
	//} else if (param.MinValue > 0 && param.MaxValue > 0) {
	//	condition["value"] = map[string]interface{}{"$gte": param.MinValue, "$lte": param.MaxValue}
	//	condition["value1"] = map[string]interface{}{"$gte": param.MinValue, "$lte": param.MaxValue}
	//}
	//
	//if (len(param.MidwayNo) == 1 && len(param.StationNo) > 0) {
	//	condition["stationno"] = map[string]interface{}{"$in": param.StationNo}
	//}
	//condition["midwayno"] = map[string]interface{}{"$in": param.MidwayNo}
	//
	//v := make([]mgos.STSwitch, 0)
	//err := this.S.HDGetAll(condition, &v)
	//if err != nil {
	//	return nil, err
	//}
	//ms := make(map[string]map[string][]mgos.STSwitch, 0)
	//for _, obj := range v {
	//	if _, ok := ms[*obj.MidWayNo]; !ok {
	//		ms[*obj.MidWayNo] = make(map[string][]mgos.STSwitch, 0)
	//	}
	//	ms[*obj.MidWayNo] = append(ms[*obj.MidWayNo], obj)
	//}
	//
	//var midways = []views.MidWay_View{}
	//for k, v := range ms {
	//	midway := new(views.MidWay_View)
	//	midway.MidwayNo = k
	//	midway.Stations = make([]views.Station_View, 0)
	//	for _, s := range v {
	//		staion := new(views.Station_View)
	//		staion.StationNo = *s.StationNo
	//		staion.Value = *s.Value
	//		if s.Value1 != nil {
	//			staion.Value1 = *s.Value1
	//		}
	//		staion.Time = *s.Time
	//		staion.Status = *s.Status
	//		midway.Stations = append(midway.Stations, *staion)
	//	}
	//	midways = append(midways, *midway)
	//}
	//return midways, nil
	return nil, nil
}

func (this *CanService) HisEfficiencyReport(param HisReposrtParam) (interface{}, error) {

	type MidWay3 struct {
		Midway   views.MidWay3_View
		Stations map[string]*views.Station3_View
	}

	var midways = []views.MidWay3_View{}

	midwayMap := make(map[string]*MidWay3, 0)
	midwayStartTimeMap := make(map[string]int64, 0)
	midwayEndTimeMap := make(map[string]int64, 0)
	midwayStationsMap := make(map[string]*utils.Set, 0)

	for _, m := range param.Midways {
		if _, ok := midwayMap[m.MidwayNo]; !ok {
			midwayMap[m.MidwayNo] = new(MidWay3)
			midwayMap[m.MidwayNo].Stations = make(map[string]*views.Station3_View, 0)
			midwayStartTimeMap[m.MidwayNo] = -1
			midwayEndTimeMap[m.MidwayNo] = -1
			midwayStationsMap[m.MidwayNo] = utils.New()
		}
		for _, t := range m.Times {
			for _, s := range t.StationNo {
				if _, ok := midwayMap[m.MidwayNo].Stations[s]; !ok {
					midwayMap[m.MidwayNo].Stations[s] = views.NewStation3View(s)
				}
			}
			if (midwayStartTimeMap[m.MidwayNo] == -1 || midwayStartTimeMap[m.MidwayNo] > t.StratTime) {
				midwayStartTimeMap[m.MidwayNo] = t.StratTime
			}
			if (midwayEndTimeMap[m.MidwayNo] == -1 || midwayEndTimeMap[m.MidwayNo] < t.EndTime) {
				midwayEndTimeMap[m.MidwayNo] = t.EndTime
			}

			midwayStationsMap[m.MidwayNo].AddAll(t.StationNo)
		}
	}

	//遍历所有中层
	for k, v := range midwayMap {
		condition := make(map[string]interface{})

		condition["time"] = map[string]interface{}{"$gt": midwayStartTimeMap[k] - 86400, "$lt": midwayEndTimeMap[k]}
		condition["stationno"] = map[string]interface{}{"$in": midwayStationsMap[k].List()}

		his := make([]mgos.HistroyEfficiency, 0)
		err := this.Ef.HDGetAll(condition, &his)
		if err != nil {
			return nil, err
		}
		mHistroyEfficiencys := make(map[string][]mgos.HistroyEfficiency, 0)
		for _, obj := range his {
			if _, ok := mHistroyEfficiencys[*obj.StationNo]; !ok {
				mHistroyEfficiencys[*obj.StationNo] = make([]mgos.HistroyEfficiency, 0)
			}
			obj.EfficiencyIndex = 47
			mHistroyEfficiencys[*obj.StationNo] = append(mHistroyEfficiencys[*obj.StationNo], obj)
		}

		//加入实时记录
		val, err := this.E.Redis.HGetAll(k).Result()
		if err != nil && val == nil {
			panic(err)
		}
		for _, sn := range midwayStationsMap[k].List() {
			var data mgos.HistroyEfficiency
			if e := json.Unmarshal([]byte(val[sn]), &data); e == nil {
				if _, ok := mHistroyEfficiencys[sn]; !ok {
					mHistroyEfficiencys[sn] = make([]mgos.HistroyEfficiency, 0)
				}
				tm := time.Unix(data.Time, 0)
				tz, _ := time.ParseInLocation("2006-01-02", tm.Format("2006-01-02"), time.Local)
				data.Time = tz.Unix()
				mHistroyEfficiencys[sn] = append(mHistroyEfficiencys[sn], data)
			}
		}

		for _, mm := range param.Midways {
			//找到对应的时间端配置
			if mm.MidwayNo == k {
				for _, tt := range mm.Times {
					//遍历所有配置的站点
					for _, ss := range tt.StationNo {
						//获取站点对应的时间数据
						for i := 0; i < len(mHistroyEfficiencys[ss]); i++ {

							//=========================================================================================================
							//*************************************挑选有效的数据段*************************************************
							//没有到配置的开始时间，则继续往下走
							if tt.StratTime-mHistroyEfficiencys[ss][i].Time > 86400 {
								continue
							}
							tm := time.Unix(mHistroyEfficiencys[ss][i].Time, 0)
							tz, _ := time.ParseInLocation("2006-01-02", tm.Format("2006-01-02"), time.Local)
							zero := tz.Unix()
							//如果最晚时间小于0点时刻，那么表示已经超过这个这个规则的最后一条，则不再执行这条规则，继续匹配下一条规则
							if tt.EndTime < zero {
								break
							}
							//========================================================================================================

							//遍历所有分段
							for _, pp := range tt.TimeParts {
								ef := new(views.Efficency_View)
								ef.StartTime = mHistroyEfficiencys[ss][i].Time + 1800*pp.Strat
								//如果开始时间超过了配置的结束时间（配置的太短），直接PASS
								if (ef.StartTime >= tt.EndTime) {
									continue
								}
								//如果开始时间比截止时间的索引大，表示跨天，这时候要考虑到可能最晚时间是超过当前时间的
								if pp.Strat > pp.End {
									ef.EndTime = mHistroyEfficiencys[ss][i].Time + 86400 + 1800*pp.End
									ef.Efficiency = 0
									for j := pp.Strat - 1; j <= mHistroyEfficiencys[ss][i].EfficiencyIndex; j++ {
										ef.Efficiency = ef.Efficiency + mHistroyEfficiencys[ss][i].Efficiency[j]
										ef.Stoptimes23 = ef.Stoptimes23 + mHistroyEfficiencys[ss][i].Stoptimes23[j]
										ef.Stoptimes27 = ef.Stoptimes27 + mHistroyEfficiencys[ss][i].Stoptimes27[j]
										ef.Stoptimes29 = ef.Stoptimes29 + mHistroyEfficiencys[ss][i].Stoptimes29[j]
										ef.Stoptimes31 = ef.Stoptimes31 + mHistroyEfficiencys[ss][i].Stoptimes31[j]
										ef.Stoptimes101 = ef.Stoptimes101 + mHistroyEfficiencys[ss][i].Stoptimes101[j]
										ef.Stoptimes201 = ef.Stoptimes201 + mHistroyEfficiencys[ss][i].Stoptimes201[j]
										if (ef.Speed < mHistroyEfficiencys[ss][i].Speed[j]) {
											ef.Speed = mHistroyEfficiencys[ss][i].Speed[j]
										}
									}
									if (len(mHistroyEfficiencys[ss]) > i+1) {
										end := pp.End - 1
										if (end > mHistroyEfficiencys[ss][i+1].EfficiencyIndex) {
											end = mHistroyEfficiencys[ss][i+1].EfficiencyIndex
										}
										for j := int64(0); j < end; j++ {
											ef.Efficiency = ef.Efficiency + mHistroyEfficiencys[ss][i+1].Efficiency[j]
											ef.Stoptimes23 = ef.Stoptimes23 + mHistroyEfficiencys[ss][i+1].Stoptimes23[j]
											ef.Stoptimes27 = ef.Stoptimes27 + mHistroyEfficiencys[ss][i+1].Stoptimes27[j]
											ef.Stoptimes29 = ef.Stoptimes29 + mHistroyEfficiencys[ss][i+1].Stoptimes29[j]
											ef.Stoptimes31 = ef.Stoptimes31 + mHistroyEfficiencys[ss][i+1].Stoptimes31[j]
											ef.Stoptimes101 = ef.Stoptimes101 + mHistroyEfficiencys[ss][i+1].Stoptimes101[j]
											ef.Stoptimes201 = ef.Stoptimes201 + mHistroyEfficiencys[ss][i+1].Stoptimes201[j]
											if (ef.Speed < mHistroyEfficiencys[ss][i+1].Speed[j]) {
												ef.Speed = mHistroyEfficiencys[ss][i+1].Speed[j]
											}
										}
									}
								} else {
									ef.EndTime = mHistroyEfficiencys[ss][i].Time + 1800*pp.End
									ef.Efficiency = 0
									end := pp.End - 1
									if (end > mHistroyEfficiencys[ss][i].EfficiencyIndex) {
										end = mHistroyEfficiencys[ss][i].EfficiencyIndex
									}
									for j := pp.Strat - 1; j < end; j++ {
										ef.Efficiency = ef.Efficiency + mHistroyEfficiencys[ss][i].Efficiency[j]
										ef.Stoptimes23 = ef.Stoptimes23 + mHistroyEfficiencys[ss][i].Stoptimes23[j]
										ef.Stoptimes27 = ef.Stoptimes27 + mHistroyEfficiencys[ss][i].Stoptimes27[j]
										ef.Stoptimes29 = ef.Stoptimes29 + mHistroyEfficiencys[ss][i].Stoptimes29[j]
										ef.Stoptimes31 = ef.Stoptimes31 + mHistroyEfficiencys[ss][i].Stoptimes31[j]
										ef.Stoptimes101 = ef.Stoptimes101 + mHistroyEfficiencys[ss][i].Stoptimes101[j]
										ef.Stoptimes201 = ef.Stoptimes201 + mHistroyEfficiencys[ss][i].Stoptimes201[j]
										if (ef.Speed < mHistroyEfficiencys[ss][i].Speed[j]) {
											ef.Speed = mHistroyEfficiencys[ss][i].Speed[j]
										}
									}
								}
								//过滤掉无效的时间
								if (ef.EndTime > time.Now().Unix()) {
									ef.StopTime = time.Now().Unix() - ef.StartTime - ef.Efficiency
								} else {
									ef.StopTime = ef.EndTime - ef.StartTime - ef.Efficiency
								}
								(v.Stations[ss]).Efficencys = append(v.Stations[ss].Efficencys, ef)
							}
						}
					}
				}
			}
		}

		v.Midway.MidwayNo = k
		v.Midway.Stations = make([]views.Station3_View, 0)
		for _, vv := range v.Stations {
			v.Midway.Stations = append(v.Midway.Stations, *vv)
		}
		midways = append(midways, v.Midway)
	}

	return midways, nil
}

func (this *CanService) RealTimeInfo() (interface{}, error) {
	var midways = views.MidWays_View{}
	midways.MidWaySize = 0
	midways.StationSize = 0
	val, err := this.E.Redis.Keys("*").Result()
	if err != nil {
		panic(err)
	}
	mvs := []views.MidWayInfo_View{}
	for _, v := range val {
		var midway views.MidWayInfo_View
		val1, err1 := this.E.Redis.HKeys(v).Result()
		if err1 == nil {
			midway.Stations = val1
			midway.MidwayNo = v
			midway.StationSize = len(val1)
			mvs = append(mvs, midway)
		}
		midways.MidWaySize = midways.MidWaySize + 1
		midways.StationSize = midways.StationSize + midway.StationSize
	}
	midways.MidWays = mvs

	return midways, nil
}

func (this *CanService) PacketInfoReport(param PacketInfoParam) (interface{}, error) {

	condition := make(map[string]interface{})

	condition["value.sn"] = param.MidwayNo
	condition["t"] = map[string]interface{}{"$gte": param.StartTime, "$lte": param.EndTime}

	v := make([]mgos.Packet, 0)
	err := this.P.HDGetAll(condition, &v)
	if err != nil {
		return nil, err
	}
	stationTimsTemp := make(map[string]int, 0)
	for _, obj := range v {
		for _, packet := range obj.Value.Packets {
			stationTimsTemp[*packet.Sn] = stationTimsTemp[*packet.Sn] + 1
		}
	}

	var stations = []views.Station4_View{}
	for k, v := range stationTimsTemp {
		station := new(views.Station4_View)
		station.StationNo = k
		station.PackSize = v
		stations = append(stations, *station)
	}
	return stations, nil
}

type CanService struct {
	E   *base.Service
	S   *base.MgoCollection
	His *base.MgoCollection
	P   *base.MgoCollection
	Ef  *base.MgoCollection
}

var canService *CanService

func NewCanService() *CanService {
	if canService == nil {
		u := new(CanService)
		u.S = base.Serve.Mgo.Raw.STSwitch
		u.His = base.Serve.Mgo.Raw.Histroy
		u.P = base.Serve.Mgo.Raw.Packet
		u.Ef = base.Serve.Mgo.Raw.Efficiency
		base.RegisterService(u)
		canService = u
	}
	return canService
}

func init() {

}
